package com.yylc.cscore.component;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author xiangnan
 * date 2018/5/7
 */
@Component
public class JobScheduler {
    private final static Logger logger = LogManager.getLogger();

    @Resource(name = "internalScheduler")
    private Scheduler scheduler;

    /**
     * 检查cron表达式，合法的话返回 最近5次运行时间
     */
    public List<String> checkCron(String cron) {
        if (StrUtil.isBlank(cron)) {
            return CollectionUtil.newArrayList("cron为空");
        }

        try {
            if (CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing() == null) {
                return CollectionUtil.newArrayList("cron表达式不合法");
            }
        } catch (Exception e) {
            return CollectionUtil.newArrayList("cron表达式不合法");
        }

        // 获取最近5次运行时间
        String result = HttpUtil.get("http://www.pppet.net/preview?CronExpression=" +
                StrUtil.trim(cron).replace(" ", "%20"), 10000);
        return CollectionUtil.newArrayList(StrUtil.split(result.trim().substring(1, result.length() - 1), ","));
    }

    /**
     * 添加任务
     * @param name jobId
     * @param group groupId
     * @param cron cron表达式
     */
    public void addJob(String name, String group, String cron) {
        if (StrUtil.isBlank(name) || StrUtil.isBlank(group) || StrUtil.isBlank(cron)) {
            throw new RuntimeException("参数错误");
        }

        if (exists(name, group)) {
            return;
        }

        // 检查cron
        CronTrigger cronTrigger;
        try {
            CronScheduleBuilder cronScheduleBuilder =
                    CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing();
            cronTrigger =
                    TriggerBuilder.newTrigger().withIdentity(name, group).withSchedule(cronScheduleBuilder).build();
        } catch (Exception e) {
            throw new RuntimeException("cron表达式错误");
        }

        try {
            // 添加任务
            JobDetail jobDetail = JobBuilder.newJob(JobBean.class).withIdentity(name, group).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);

            logger.info("添加任务成功: jobDetail: {}", jobDetail);
        } catch (Exception e) {
            throw new RuntimeException("quartz错误 " + e.toString());
        }
    }

    /**
     * 手工触发任务执行
     */
    public void triggerJob(String name, String group) {
        if (!exists(name, group)) {
            logger.warn("未找到任务: name: {}, group: {}", name, group);
            return;
        }

        try {
            JobKey jobKey = new JobKey(name, group);
            scheduler.triggerJob(jobKey);
            logger.info("触发任务成功，jobKey: {}", jobKey);
        } catch (Exception e) {
            logger.info("触发任务失败, Quartz错误: " + e);
            throw new RuntimeException("触发任务失败, Quartz错误: " + e.getMessage());
        }
    }

    /**
     * 暂停任务
     * @param name jobId
     * @param group groupId
     */
    public void pauseJob(String name, String group) {
        if (!exists(name, group)) {
            logger.warn("未找到任务: name: {}, group: {}", name, group);
            return;
        }

        try {
            JobKey jobKey = new JobKey(name, group);
            scheduler.pauseJob(jobKey);
            logger.info("暂停任务成功，jobKey: {}", jobKey);
        } catch (Exception e) {
            logger.info("暂停任务失败, Quartz错误: " + e);
            throw new RuntimeException("暂停任务失败, Quartz错误: " + e.getMessage());
        }
    }
    /**
     * 恢复任务
     * @param name jobId
     * @param group groupId
     */
    public void resumeJob(String name, String group) {
        if (!exists(name, group)) {
            logger.warn("未找到任务: name: {}, group: {}", name, group);
            return;
        }

        try {
            JobKey jobKey = new JobKey(name, group);
            scheduler.resumeJob(jobKey);
            logger.info("恢复任务成功，jobKey: {}", jobKey);
        } catch (Exception e) {
            logger.info("恢复任务失败, Quartz错误: " + e);
            throw new RuntimeException("恢复任务失败, Quartz错误: " + e.getMessage());
        }
    }

    /**
     * 删除任务
     * @param name jobId
     * @param group jobId
     */
    public void deleteJob(String name, String group) {
        if (!exists(name, group)) {
            logger.warn("未找到任务: name: {}, group: {}", name, group);
            return;
        }

        try {
            TriggerKey triggerKey = new TriggerKey(name, group);
            scheduler.unscheduleJob(triggerKey);
            logger.info("删除任务成功，triggerKey: {}", triggerKey);
        } catch (Exception e) {
            logger.info("删除任务失败, Quartz错误: " + e);
            throw new RuntimeException("删除任务失败, Quartz错误: " + e.getMessage());
        }
    }

    public boolean exists(String name, String group) {
        try {
            return scheduler.checkExists(new TriggerKey(name, group));
        } catch (Exception e) {
            throw new RuntimeException("quartz错误 " + e.getMessage());
        }
    }

}
